package commMqttRpc

import (
	"errors"
	"fmt"
	"gitee.com/fierce_wolf/go-fox-edge-common/commMqtt"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/ChanSyncObj"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Uuid"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"strings"
	"time"
)

type mqttClient struct {
	client *commMqtt.MqttClient
}

func (e *mqttClient) GetDefaultHandler() mqtt.MessageHandler {
	return func(client mqtt.Client, msg mqtt.Message) {
		fmt.Printf("TOPIC: %s\n", msg.Topic())
		fmt.Printf("MSG: %s\n", msg.Payload())
	}
}

func (e *mqttClient) Instance(options map[string]interface{}, edgeId, request, respond string) {
	clientId := Map.GetString(options, "clientId", "")
	if clientId == "" {
		clientId = Uuid.RandomUUID()
	}

	if request == "" || respond == "" {
		return
	}

	request = strings.ReplaceAll(request, "{edgeId}", edgeId)
	respond = strings.ReplaceAll(respond, "{edgeId}", edgeId)

	// 设置MQTT的通信参数
	e.client = commMqtt.NewClient(clientId, options)

	// 向MQTT BROKER注册订阅topic
	handler.clientId = clientId
	handler.topic = respond
	e.client.Subscribe(respond, handler.Handler())

	// 开始连接
	go e.connect()
}

func (e *mqttClient) connect() {
	time.Sleep(3 * time.Second)
	for e.client.Connect() != nil {
		time.Sleep(3 * time.Second)
	}
}

func (e *mqttClient) request(requestVO *RestfulLikeRequestVO) (respondVO *RestfulLikeRespondVO, err error) {
	// 检查：参数是否为空
	if requestVO == nil || Method.HasEmpty(requestVO.Topic, requestVO.Method, requestVO.Resource, requestVO.Uuid) {
		return nil, errors.New("参数缺失：topic, uuid, resource, method")
	}

	// 将消息推送给mqtt broker
	jsn := Json.BuildJson(requestVO)
	if !client.client.Publish(requestVO.Topic, jsn, 15*1000) {
		return nil, errors.New("发送失败：requestVO =>> mqtt broker")
	}

	// 等待消息到达：根据uuid等待fox-edge的消息返回
	message := ChanSyncObj.SimpleWait(requestVO.Uuid, 15*1000)
	if message == nil {
		return nil, errors.New("响应超时：respondVO =>> mqtt broker")
	}

	respondVO = message.(*RestfulLikeRespondVO)
	return respondVO, nil
}
